import { Badge, Spin } from 'antd'
import type { Dayjs } from 'dayjs'
import { FC, useCallback, useEffect, useState } from 'react'

import { useScheduleStore } from '@/stores/scheduleStore'
import { dayjs } from '@/utils/dayjs'

/**
 * 日历组件Props接口
 */
interface ScheduleCalendarProps {
  onDateStatusClick: (date: string, status: string) => void
}

/**
 * 日程状态配置
 */
const STATUS_CONFIG = [
  { key: 'planning', label: '计划中', color: 'warning' as const, badgeType: 'warning' as const },
  {
    key: 'inProgress',
    label: '进行中',
    color: 'processing' as const,
    badgeType: 'processing' as const
  },
  { key: 'pendingReview', label: '待审核', color: 'error' as const, badgeType: 'error' as const }
] as const

/**
 * 日程日历组件
 * 显示当前用户作为执行人的日程统计，支持按日期和状态筛选
 */
const ScheduleCalendar: FC<ScheduleCalendarProps> = ({ onDateStatusClick }) => {
  // Store状态
  const calendarData = useScheduleStore(state => state.calendarData)
  const calendarLoading = useScheduleStore(state => state.calendarLoading)
  const fetchCalendarData = useScheduleStore(state => state.fetchCalendarData)
  const setCalendarRange = useScheduleStore(state => state.setCalendarRange)

  // 组件内部状态
  const [currentDate] = useState(dayjs())

  // 计算当前周及前后各一周的日期范围（共三周，21天）
  useEffect(() => {
    // 获取当前周的开始日期（周一）
    const currentWeekStart = currentDate.startOf('week')
    // 获取前一周的开始日期
    const prevWeekStart = currentWeekStart.subtract(1, 'week')
    // 获取后一周的开始日期
    const nextWeekStart = currentWeekStart.add(1, 'week')

    // 计算三周的开始和结束日期（21天：前一周7天 + 当前周7天 + 后一周7天）
    const startDate = prevWeekStart.format('YYYY-MM-DD')
    const endDate = nextWeekStart.add(6, 'day').format('YYYY-MM-DD')

    // 保存区间供统一刷新使用
    setCalendarRange({ startDate, endDate })
    // 首次拉取或区间变化时拉取
    fetchCalendarData(startDate, endDate)
  }, [currentDate, fetchCalendarData, setCalendarRange])

  /**
   * 获取三周的日期数组
   */
  const getWeeksData = useCallback((): Dayjs[][] => {
    const weeks: Dayjs[][] = []
    const currentWeekStart = currentDate.startOf('week')

    // 前三周
    for (let weekOffset = -1; weekOffset <= 1; weekOffset++) {
      const weekStart = currentWeekStart.add(weekOffset, 'week')
      const week: Dayjs[] = []
      for (let day = 0; day < 7; day++) {
        week.push(weekStart.add(day, 'day'))
      }
      weeks.push(week)
    }

    return weeks
  }, [currentDate])

  /**
   * 获取某日的日程统计数据
   */
  const getDayData = useCallback(
    (date: Dayjs) => {
      if (!calendarData) return null

      const dateStr = date.format('YYYY-MM-DD')
      return calendarData.find(item => item.date === dateStr) || null
    },
    [calendarData]
  )

  /**
   * 处理日期单元格点击
   */
  const handleDayClick = useCallback(
    (date: Dayjs) => {
      const dateStr = date.format('YYYY-MM-DD')
      onDateStatusClick(dateStr, '')
    },
    [onDateStatusClick]
  )

  /**
   * 判断是否是今天
   */
  const isToday = useCallback((date: Dayjs) => {
    return date.isSame(dayjs(), 'day')
  }, [])

  // 星期标题
  const weekDays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
  const weeks = getWeeksData()

  return (
    <div className="mb-6 w-full rounded-lg border border-gray-300 bg-white p-5 shadow-sm">
      <Spin spinning={calendarLoading}>
        <div className="w-full overflow-x-auto">
          <div className="inline-block min-w-full">
            {/* 星期标题行 */}
            <div className="mb-3 flex w-full">
              <div className="w-[100px] text-sm font-medium text-gray-500">
                <div className="py-2 text-center">周数</div>
              </div>
              <div className="flex flex-1">
                {weekDays.map(day => (
                  <div
                    key={day}
                    className="flex-1 text-center text-sm font-medium text-gray-700"
                  >
                    <div className="py-2">{day}</div>
                  </div>
                ))}
              </div>
            </div>

            {/* 三周数据行 */}
            {weeks.map((week, weekIndex) => (
              <div
                key={weekIndex}
                className="mb-2 flex w-full"
              >
                {/* 周标题 */}
                <div className="w-[100px] text-sm text-gray-600">
                  {weekIndex === 0 && <div className="py-2 text-center">上周</div>}
                  {weekIndex === 1 && <div className="py-2 text-center">本周</div>}
                  {weekIndex === 2 && <div className="py-2 text-center">下周</div>}
                </div>

                {/* 日期单元格 */}
                <div className="flex flex-1 gap-2">
                  {week.map((date, dayIndex) => {
                    const dayData = getDayData(date)
                    const isCurrentToday = isToday(date)
                    const dateStr = date.format('MM-DD')

                    return (
                      <div
                        key={dayIndex}
                        className={`relative flex flex-1 cursor-pointer flex-col rounded-lg border ${isCurrentToday ? 'border-blue-400 shadow-md' : 'border-gray-200'} bg-white p-2 transition-all hover:border-blue-400 hover:shadow-md`}
                        style={{ minHeight: '66px' }}
                        onClick={() => handleDayClick(date)}
                        onKeyDown={e => {
                          if (e.key === 'Enter' || e.key === ' ') {
                            handleDayClick(date)
                          }
                        }}
                        role="button"
                        tabIndex={0}
                      >
                        {/* 日期标题 */}
                        <div className="mb-2 flex items-center gap-1">
                          <span
                            className={`text-sm font-medium ${
                              isCurrentToday ? 'text-blue-600' : 'text-gray-700'
                            }`}
                          >
                            {dateStr}
                          </span>
                          {isCurrentToday && (
                            <span
                              className="rounded px-1.5 py-0.5 text-xs text-blue-500"
                              style={{ background: '#e6f7ff' }}
                            >
                              今天
                            </span>
                          )}
                        </div>

                        {/* 日程状态列表 */}
                        <div className="flex flex-1 flex-col gap-1">
                          {dayData ? (
                            STATUS_CONFIG.map(status => {
                              const count = dayData[status.key as keyof typeof dayData] as number
                              if (count === 0) return null
                              return (
                                <div
                                  key={status.key}
                                  className="flex items-center gap-1 text-[11px]"
                                >
                                  <Badge
                                    status={status.badgeType}
                                    text={`${status.label}（${count}项）`}
                                  />
                                </div>
                              )
                            })
                          ) : (
                            <div className="flex items-center text-xs text-gray-400">暂无日程</div>
                          )}
                        </div>
                      </div>
                    )
                  })}
                </div>
              </div>
            ))}
          </div>
        </div>
      </Spin>
    </div>
  )
}

export default ScheduleCalendar
